#ifndef __LEARNDX_CTIMER_H_INCLUDE__
#define __LEARNDX_CTIMER_H_INCLUDE__
#include "IReferenceCounted.h"

namespace ldx
{
	namespace device
	{
		//! Interface for getting and manipulating the  time
		// Not thread safe.ms based.
		class CTimer : public virtual IReferenceCounted
		{
		public:

			//! Get the system's clock,in second
			static double getSystemRealTime();

			//! init for system timer
			/* This function must be caled before game while
			* and before using function get of this class.*/
			static void initSystemTimer();

			//! update system timer,this should be call in game while every frame
			static void updateSystemTimer();

			//! get system timer's delta time,in ms.
			static float getSystemDeltaTime();

			//! sleep the system in second.such 1.0 second
			static void sleepSystem(double sleepTime);

		public:
			//explicit
			CTimer(float startTimeSeconds = 0.f);

			//! destructor
			~CTimer();

			//! Return time ticks of time cycle.
			unsigned long  getTimeCycles() const;

			//Cacl this timer - other timer,in second
			float caclDetaSeconds(const CTimer& other);

			//! Advances the  time,update,second,even go back
			//\param dtRealDeltaSeconds in ms.
			void update(float dtRealDeltaSeconds);

			//! Return local timer's delta time in ms.
			float getDeltaTime() const;

			//! Stops the  timer.
			void setPaused();

			//! Starts the  timer.
			void setStart();

			//! Sets the speed of the timer
			void setSpeed(float speed = 1.0f);

			//! Returns current speed of the timer
			float getSpeed() const;

			//! Returns if the  timer is currently stopped
			bool isStopped() const;

			float getCyclesFrequency()const;

			//! just step one frame's time,
			/*but should be paused before use this.
			\param timeEachFrame time of one frame ,such 1.f/30.f
			*/
			void singleStep(float timeEachFrame = 1.f / 30.f);
		protected:
			unsigned long  mTimeCycles;//current
			float mDeltaTime;//seconds

			float mTimeScale;
			bool mIsPasued;

			static bool firstTimeNew;
			static double msSystemCurrentTime;
			static double msSystemLastTime;
			static float msSystemdeltaTime;
			static float msCyclesPerSecond;

			static inline unsigned long  secondsToCycles(float timeSeconds)
			{
				return (unsigned long )(timeSeconds*msCyclesPerSecond);
			}
			//warning: only transform short time to second
			static inline float cyclesToSeconds(unsigned long  timeCycles)
			{
				return (float)(timeCycles / msCyclesPerSecond);
			}
		};
	}
}
#endif